package com.wechat.page.chat.content.chatting;

import java.util.Collection;
import java.util.List;

import com.swak.fx.support.AbstractComp;
import com.swak.fx.support.FXMLView;
import com.swak.fx.support.ui.UI.Locations;
import com.swak.fx.support.ui.UIBorderPane;
import com.swak.fx.support.ui.UIImage;
import com.swak.fx.support.ui.UIPopup;
import com.swak.fx.support.ui.UIScrollPaneInner;
import com.wechat.face.Category;
import com.wechat.face.Face;
import com.wechat.face.Faces;

import javafx.beans.property.ListProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;

/**
 * FacesSelectComp.
 * 
 * @author 618lf
 */
@FXMLView(title = "表情选择", value = "FacesSelectComp.fxml", css = "FacesSelectComp.css")
public class FacesSelectComp extends AbstractComp {

	@FXML
	private HBox actions;
	@FXML
	private UIScrollPaneInner scroll;
	private GridPane faceGrid;

	private UIPopup popup;
	private UIBorderPane borderPane;

	public FacesSelectComp() {
		this.popup = new UIPopup();
		this.borderPane = new UIBorderPane();
		this.faceGrid = new GridPane();
	}

	@Override
	protected void useComputedSize() {
		this.root.setMinHeight(-1);
		this.root.setMaxHeight(-1);
		this.root.setMinWidth(-1);
		this.root.setMaxWidth(-1);
	}

	@Override
	public void initializeParts() {
		super.initializeParts();
		this.borderPane.setContentNode(this.root);
		this.popup.setContentNode(borderPane);
		this.popup.setPrefWidth(415);
		this.popup.setPrefHeight(380);
		this.popup.locationProperty().set(Locations.BOTTOM_CENTER);
		this.actions.setAlignment(Pos.CENTER_LEFT);
		this.scroll.setContent(faceGrid);
		this.scroll.setFitToWidth(true);
	}

	@Override
	public void setupEventHandlers() {
		super.setupEventHandlers();
		this.actions.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
			Node node = (Node) e.getTarget();
			if (node instanceof UIImage) {
				Category category = (Category) ((UIImage) node).getProperties().get("data");
				this.activeProperty().set(category);
			}
		});
		this.faceGrid.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
			Node node = (Node) e.getTarget();
			if (node instanceof UIImage) {
				Face face = (Face) ((UIImage) node).getProperties().get("data");
				this.$emit("face:select", face);
				this.popup.hide();
			}
		});
	}

	@Override
	public void setupValueChangedListeners() {
		super.setupValueChangedListeners();
		this.categoryProperty().addListener(new ListChangeListener<Category>() {
			@Override
			public void onChanged(Change<? extends Category> c) {
				FacesSelectComp.this.onCategoryChange(c);
			}
		});
		this.activeProperty().addListener((ob, o, n) -> this.onCategorySelect(n));
	}

	private void onCategorySelect(Category category) {
		this.actions.getChildren().forEach(child -> {
			child.getStyleClass().remove("active");
			if (child instanceof UIImage) {
				Category _category = (Category) ((UIImage) child).getProperties().get("data");
				if (_category == category) {
					child.getStyleClass().add("active");
				}
			}
		});

		List<Face> faces = Faces.findFaces(category);
		this.faceGrid.getChildren().clear();

		int maxColumns = 10;
		int col = 0;
		int row = 0;
		for (int i = 0; i < faces.size(); i++) {
			Face face = faces.get(i);
			UIImage image = new UIImage().image(face.getShowPath());
			image.setPrefSize(30, 30);
			image.getProperties().put("data", face);
			col = col % maxColumns + 1;
			if (col == 1) {
				row++;
			}
			this.faceGrid.add(image, col, row);
			GridPane.setFillHeight(image, true);
			GridPane.setFillWidth(image, true);
		}
	}

	@SuppressWarnings("unchecked")
	private void onCategoryChange(Change<? extends Category> c) {
		while (c.next()) {
			if (c.wasPermutated()) {

			} else if (c.wasAdded()) {
				List<Category> adds = (List<Category>) c.getAddedSubList();
				for (Category chat : adds) {
					this.onAddChat(chat);
				}
			} else if (c.wasRemoved()) {

			} else if (c.wasUpdated()) {

			} else if (c.wasReplaced()) {

			}
		}
	}

	private void onAddChat(Category msg) {
		Face face = msg.getFace();
		UIImage image = new UIImage().image(face.getShowPath());
		image.setPrefSize(30, 30);
		image.getProperties().put("data", msg);
		this.actions.getChildren().add(image);
	}

	@Override
	public void initializeFinish() {
		super.initializeFinish();

		// 分类
		Collection<Category> categorys = Faces.getCategorys();
		this.categoryProperty().addAll(categorys);
		this.activeProperty().set(categorys.stream().findFirst().get());
	}

	public void show(Node node) {
		this.popup.show(node, 15);
	}

	// ================================================================================
	// Properties
	// ================================================================================
	private final ListProperty<Category> categoryProperty = new SimpleListProperty<>(
			FXCollections.observableArrayList());

	public ListProperty<Category> categoryProperty() {
		return categoryProperty;
	}

	private final ObjectProperty<Category> activeProperty = new SimpleObjectProperty<Category>();

	public ObjectProperty<Category> activeProperty() {
		return activeProperty;
	}
}